/*
 * Created by LiuYou on 2020/12/23.
 *
 */

#include "Pcb.hpp"
#include <utility>

Pcb::Pcb(std::string name, int needExecutionTime, ProcessStatus processStatus, int priorityNum, int executionCount,
         int executedTimeOnCpu, int timeSlice, Pcb* next) : name(std::move(name)),
                                                            processStatus(processStatus),
                                                            priorityNum(priorityNum),
                                                            needExecutionTime(needExecutionTime),
                                                            executionCount(executionCount),
                                                            executedTimeOnCpu(executedTimeOnCpu),
                                                            timeSlice(timeSlice), next(next) {}

const std::string& Pcb::getName() const {
    return name;
}

ProcessStatus Pcb::getProcessStatus() const {
    return processStatus;
}

int Pcb::getPriorityNum() const {
    return priorityNum;
}

int Pcb::getNeedExecutionTime() const {
    return needExecutionTime;
}

int Pcb::getExecutionCount() const {
    return executionCount;
}

int Pcb::getExecutedTimeOnCpu() const {
    return executedTimeOnCpu;
}

int Pcb::getTimeSlice() const {
    return timeSlice;
}

Pcb* Pcb::getNext() const {
    return next;
}

/*std::ostream& operator<<(std::ostream& os, const Pcb& pcb) {
    os << "name: " << pcb.name << " processStatus: " << []() -> std::string {
        if (pcb.processStatus == ProcessStatus::BLOCKED) {
            return "BLOCKED";
        } else if (pcb.processStatus == ProcessStatus::RUNNING) {
            return "RUNNING";
        } else if (pcb.processStatus == ProcessStatus::TERMINAL) {
            return "TERMINAL";
        }
    } << pcb.processStatus << " priorityNum: "
       << pcb.priorityNum
       << " needExecutionTime: " << pcb.needExecutionTime << " executionCount: " << pcb.executionCount
       << " executedTimeOnCpu: " << pcb.executedTimeOnCpu << " timeSlice: " << pcb.timeSlice << " next: " << pcb.next;
    return os;
}*/


/*
std::ostream& operator<<(std::ostream& os, const Pcb& pcb) {
    os << "进程名称: " << pcb.name << " 进程当前状态: " << [](const Pcb& pcb) -> std::string {
        if (pcb.processStatus == BLOCKED) {
            return std::string("BLOCKED");
        } else if (pcb.processStatus == ProcessStatus::RUNNING) {
            return std::string("RUNNING");
        } else if (pcb.processStatus == ProcessStatus::TERMINAL) {
            return std::string("TERMINAL");
        } else {
            return std::string();
        }
    } << " 优先级: "
       << pcb.priorityNum
       << " 需要执行时间: " << pcb.needExecutionTime << " 在处理机上执行计数: " << pcb.executionCount
       << " 在处理机上的执行时间: " << pcb.executedTimeOnCpu << " 时间片: " << pcb.timeSlice << " 下一个进程: " << pcb.next;
    return os;
}*/


std::ostream& operator<<(std::ostream& os, const Pcb& pcb) {
    auto func = [](const Pcb& pcb) -> std::string {
        if (pcb.processStatus == BLOCKED) {
            return "blocked";
        } else if (pcb.processStatus == ProcessStatus::RUNNING) {
            return "running";
        } else if (pcb.processStatus == ProcessStatus::TERMINAL) {
            return "terminal";
        } else {
            return "";
        }
    };
    os << pcb.name << "={" << "进程名称N = " << pcb.name << ", 进程当前状态S = " << func(pcb) << ", 优先级P = " << pcb.priorityNum
       << ", 需要执行时间T = " << pcb.needExecutionTime << ", 在处理机上执行计数C = " << pcb.executionCount << ", 在处理机上的执行时间T = "
       << pcb.executedTimeOnCpu << ", 时间片T = " << pcb.timeSlice << ", 下一个进程N = " << pcb.next << "}";
    return os;
}